package org.zyj.io.secret;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class EncryptDemo {


    private static final String ALGORITHM = "AES";//加密算法

    private static final String WORK_MODE = "ECB";//分组加密的工作模式; 有ECB、CBC、CTR、GCM，其中ECB是最简单的加密模式。

    private static final String PADDING_MODE = "PKCS5Padding";//补码方式

    private static final String TRANSFORMATION = ALGORITHM + "/" + WORK_MODE + "/" + PADDING_MODE;


    public static void main(String[] args) throws Exception {
        String content = "你吃过了吗???!@*&#T^!*&IU@#R$UHDFYGUI*(&YFkjiol123456789";
        String key = "qwertyuiop[]!@#$"; //秘钥长度需要为128bit,也就是16字节
        String encryptedString = encrypt(content, key);
        System.out.println(encryptedString);
        String decryptedStr = decrypt(encryptedString, key);
        System.out.println(decryptedStr);
    }

    /**
     * 使用 AES/ECB/PKCS5Padding 方式加密
     *
     * @param content  待加密的原始报文
     * @param password 秘钥, 长度为128bit,也就是16字节
     * @return 返回Base64 encode之后的 字符串
     */
    public static String encrypt(String content, String password) throws Exception {
        //1. 先获取原报文的二进制数据, 使用UTF8编码进行转化
        byte[] byteContent = content.getBytes(StandardCharsets.UTF_8);//原报文指定使用UTF8编码进行编码
        //2. 对二进制数据进行加密
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);//根据算法获取Cipher对象
        SecretKeySpec key = new SecretKeySpec(password.getBytes(), ALGORITHM);//生成秘钥对象
        cipher.init(Cipher.ENCRYPT_MODE, key);//初始化算法
        byte[] encryptedData = cipher.doFinal(byteContent);//进行加密操作, 加密后的数据是二进制数据
        //3. 对加密后的二进制数据, 进行Base64转码, Base64使用 ISO_8859_1 编码进行转换
        //为了方便使用HTTP协议传输,使用Base64, Base64是一种基于 64 个可打印字符来表示二进制数据的表示方法
        Base64.Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(encryptedData); //通过Base64算法, 转化为一串 ISO_8859_1 编码的字符串, 方便网络传输
    }

    /**
     * 使用 AES/ECB/PKCS5Padding 方式解密
     *
     * @param encryptedString 已经被加密的数据
     * @param password        秘钥, 长度为128bit,也就是16字节
     * @return 返回原始报文
     */
    public static String decrypt(String encryptedString, String password) throws Exception {
        //1. 先用Base64方式得到加密的报文
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] encryptedData = decoder.decode(encryptedString);//将ISO_8859_1 编码的字符串转化为 二进制形式
        //2. 再通过加密的报文解密, 获取原始报文
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);//根据算法获取Cipher对象
        SecretKeySpec key = new SecretKeySpec(password.getBytes(), ALGORITHM);//生成秘钥对象
        cipher.init(Cipher.DECRYPT_MODE, key);//初始化算法
        byte[] result = cipher.doFinal(encryptedData);//对加密的二进制数据,按照指定算法进行解密
        //3. 原始报文是使用的UTF8编码格式
        return new String(result, StandardCharsets.UTF_8);
    }
}
